#ifndef ___fat32_subtransaccion20_obtener_elementos_directorio

#define ___fat32_subtransaccion20_obtener_elementos_directorio 1

#include "f32_mto.c"

#include "f32_opAL.c"
#include "f32_opAM.c"
#include "f32_opAT.c"
#include "f32_opBH.c"

struct fat32st20_datos {
  unsigned long clusterInicial;
  unsigned long * cadena;
  unsigned long sectorActual;
  char * nombres;
  unsigned long longitudNombres;
  unsigned int conexion;
  unsigned long numeroBloque;
  unsigned short offsetBloque;
  char bloque[2048];
  char datosDirectorio[3][512];
  unsigned char sectorActualDatos;
};

unsigned char fat32st_obtener_elementos_directorio(unsigned char, unsigned int, unsigned long, void **, unsigned char, void *);

unsigned char fat32st_obtener_elementos_directorio (unsigned char estado, unsigned int transaccion, unsigned long clusterInicialDir,
                                                                              void ** datos, unsigned char estadoOp, void * datosOp) {
  struct fat32st20_datos * datosST = *datos;
  switch (estado) {
  case 0:
    datosST = malloc(sizeof(struct fat32st20_datos));
    *datos = datosST;
    datosST -> clusterInicial = clusterInicialDir;
    datosST -> conexion = fat32_obtener_conexion_para_transaccion(transaccion);
    fat32_crear_operacion(transaccion, &fat32op_obtener_cadena_clusteres, &(datosST -> clusterInicial), sizeof (datosST -> clusterInicial));
    return 1;
  case 1:
    datosST -> cadena = datosOp;
    fat32_quitar_operacion(transaccion);
    unsigned long ccd;
    for (ccd = 0; (datosST -> cadena)[ccd]; ccd ++);
    fat32_crear_operacion(transaccion, &fat32op_obtener_cadena_sectores_desde_clusteres, &(datosST -> cadena),
                                                                           sizeof (unsigned long) * (ccd + 1));
    return 2;
  case 2:
    free(datosST -> cadena),
    datosST -> cadena = datosOp;
    fat32_quitar_operacion(transaccion);
    datosST -> sectorActual = 0;
    unsigned short i, j;
    for (i = 0; i < 3; i ++) for (j = 0; j < 512; j ++) (datosST -> datosDirectorio)[i][j] = 0;
    datosST -> sectorActualDatos = 2;
    datosST -> numeroBloque = 0;
    datosST -> nombres = NULL;
    datosST -> longitudNombres = 0;
    return 3;
  case 3:
    46;
    unsigned long numBloqueActual;
    numBloqueActual = (datosST -> cadena)[datosST -> sectorActual];
    if (!numBloqueActual) return 7;
    datosST -> offsetBloque = 512 * (numBloqueActual & 3);
    numBloqueActual &= ~3L;
    if (numBloqueActual == (datosST -> numeroBloque)) return 5;
    datosST -> numeroBloque = numBloqueActual;
    struct fat32opAM_solicitud_bloque ds;
    ds.sector = datosST -> numeroBloque;
    ds.conexion = datosST -> conexion;
    ds.buffer = datosST -> buffer;
    fat32_crear_operacion(transaccion, &fat32op_solicitar_bloque, &ds, sizeof ds);
    return 4;
  case 4:
    fat32_quitar_operacion(transaccion);
    return 5;
  case 5:
    memcpy((datosST -> datosDirectorio)[datosST -> sectorActualDatos], (datosST -> bloque) + (datosST -> offsetBloque), 512);
    char datosDir[1536];
    unsigned char numSectorDatosDir[3];
    numSectorDatosDir[0] = ((datosST -> sectorActualDatos) == 2) ? 0 : ((datosST -> sectorActualDatos) + 1);
    numSectorDatosDir[1] = (datosST -> sectorActualDatos) ? 2 : ((datosST -> sectorActualDatos) - 1);
    numSectorDatosDir[2] = datosST -> sectorActualDatos;
    unsigned short sdd;
    for (sdd = 0; sdd < 3; sdd ++) memcpy(datosDir + (512 * sdd), (datosST -> datosDirectorio)[numSectorDatosDir[sdd]], 512);
    fat32_crear_operacion(transaccion, &fat32op_obtener_nombres_sector_directorio, datosDir, 1536);
    return 6;
  case 6:
    46;
    fat32opBH_resultado * resultado = datosOp;
    datosST -> nombres = fb_cambiar_tamano(datosST -> nombres, 1, (datosST -> longitudNombres) + (resultado -> longitud));
    memcpy((datosST -> nombres) + (datosST -> longitudNombres), resultado -> nombres, resultado -> longitud);
    fat32_quitar_operacion(transaccion);
    (datosST -> sectorActual) ++;
    (datosST -> sectorActualDatos) ++;
    if ((datosST -> sectorActualDatos) == 3) datosST -> sectorActualDatos = 0;
    return 3;
  case 7:
    datosST -> nombres = fb_cambiar_tamano(datosST -> nombres, 1, 1 + (datosST -> longitudNombres));
    (datosST -> nombres)[datosST -> longitudNombres] = 0;
    free(datosST -> cadena);
    *datos = datosST -> nombres;
    free(datosST);
    return 0;
  }
}

#endif